/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023.
 * Description: support irq_chip_set/get_priority functions
 * Author: huyizhou
 * Create: 2023-09-13
 */

#include <linux/irq.h>
#include "internals.h"

int irq_chip_set_priority_parent(struct irq_data *data, u8 prio)
{
	data = data->parent_data;
	if (data->chip->irq_set_priority)
		return data->chip->irq_set_priority(data, prio);

	return -ENOSYS;
}

int irq_chip_get_priority_parent(struct irq_data *data, u8 *prio)
{
	data = data->parent_data;
	if (data->chip->irq_get_priority)
		return data->chip->irq_get_priority(data, prio);

	return -ENOSYS;
}

static int irq_do_set_priority(struct irq_data *data, const u8 prio)
{
	struct irq_chip *chip = irq_data_get_irq_chip(data);

	if (!chip || !chip->irq_set_priority)
		return -EINVAL;

	return chip->irq_set_priority(data, prio);
}

int irq_set_priority(unsigned int irq, const u8 prio)
{
	unsigned long flags;
	struct irq_desc *desc = irq_to_desc(irq);
	int ret;
#ifdef CONFIG_FIQ_GLUE
	if (check_fiq_num(irq))
		return -EINVAL;
#endif
	if (!desc)
		return -EINVAL;

	raw_spin_lock_irqsave(&desc->lock, flags);
	ret = irq_do_set_priority(irq_desc_get_irq_data(desc), prio);
	raw_spin_unlock_irqrestore(&desc->lock, flags);

	return ret;
}
EXPORT_SYMBOL_NS(irq_set_priority, HW_RTOS_NS);

int irq_get_priority(unsigned int irq, u8 *prio)
{
	struct irq_data *data = irq_get_irq_data(irq);
	struct irq_chip *chip = NULL;

	if (!data)
		return -EINVAL;

	chip = irq_data_get_irq_chip(data);
	if (!chip || !chip->irq_get_priority)
		return -EINVAL;

	return chip->irq_get_priority(data, prio);
}
EXPORT_SYMBOL_NS(irq_get_priority, HW_RTOS_NS);
